<template>
  <div style="width: 100%; height: 100%"></div>
</template>

<script>
import {
  Scene,
  PerspectiveCamera,
  WebGLRenderer,
  BoxGeometry,
  CubeGeometry,
  PlaneGeometry,
  Mesh,
  MeshLambertMaterial,
  SpotLight,
  AmbientLight
} from 'three'
import Detector from 'three/examples/js/Detector'
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      ele: null,
      width: 0,
      height:0,
      cube: null
    }
  },
  mounted() {
    this.ele = this.$el
    this.width = this.$el.clientWidth
    this.height = this.$el.clientHeight

    if (!Detector.webgl) {
      const warning = Detector.getWebGLErrorMessage()
      this.ele.appendChild(warning)
    }
    this.threeStart()
  },
  methods: {
    threeStart () {
      this.initThree()
      this.initScene()
      this.initCamera()
      this.initPlane()
      this.initLight()
      this.addGeometry()
      this.render()
    },
    initThree () {
      this.renderer = new WebGLRenderer({
        antialias : true // 是否弱化锯齿特性，true表示弱化，更消耗cpu
      })
      this.renderer.setSize(this.width, this.height)
      this.ele.appendChild(this.renderer.domElement)
      this.renderer.setClearColor(0x000000)
      this.renderer.shadowMap.enabled = true
    },
    initCamera () {
      this.camera = new PerspectiveCamera(45, this.width / this.height, 0.1, 1000)
      this.camera.position.x = -30
      this.camera.position.y = 40
      this.camera.position.z = 30
      this.camera.lookAt(this.scene.position)
    },
    initScene () {
      this.scene = new Scene()
    },
    initPlane () {
      const planeGeometry = new PlaneGeometry(60, 40, 1, 1)
      const planeMaterial = new MeshLambertMaterial({ color: '#ffffff' })
      const plane = new Mesh(planeGeometry, planeMaterial)
      plane.receiveShadow = true
      plane.rotation.x = -0.5 * Math.PI
      plane.position.x = 0
      plane.position.y = 0
      plane.position.z = 0
      this.scene.add(plane)
    },
    initLight () {
      const ambientLight = new AmbientLight(0x3c3c3c)
      this.scene.add(ambientLight)

      const spotLight = new SpotLight(0xffffff, 1, 180, Math.PI/4)
      spotLight.shadow.mapSize.height = 2048
      spotLight.shadow.mapSize.width = 2048
      spotLight.position.set(-40, 30, 30)
      spotLight.castShadow = true
      this.scene.add(spotLight)
    },
    addGeometry () {
      const material = new MeshLambertMaterial({color: 0x44ff44})
      const geom = new BoxGeometry(5, 8, 3)
      this.cube = new Mesh(geom, material)
      this.cube.position.y = 4
      this.cube.castShadow = true
      this.scene.add(this.cube)
    },
    render () {
      this.cube.rotation.y += 0.01
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.render)
    }
  }
}
</script>
